package org.wheel.plugins.toolkit.sql.capability;

import org.wheel.plugins.toolkit.sql.core.SqlSegment;
import org.wheel.plugins.toolkit.sql.helper.SFunction;

import java.util.Collection;
import java.util.function.Consumer;

/**
 * 集合/关联查询能力 – 一对多、多对一、多对多
 * @param <W> 子类型
 * @param <T> 主实体
 */
public interface LambdaCollection<W, T> {

    /* ================== 一对多集合 ================== */
    /**
     *
     * @param collectionFn 集合属性，可能是DTO中的对象属性，也可能是DTO中的集合属性
     * @param collectionClass 实体类，用于获取数据库的字段名
     * @return
     * @param <A>
     */
    default <A, B, C> W selectCollection(Class<A> collectionClass, SFunction<B, Collection<C>> collectionFn) {
        return selectCollection(collectionClass, collectionFn, null);
    }
    default <A, B, C, D extends LambdaSubCollection<D, E>, E> W  selectCollection(Class<A> collectionClass, SFunction<B, Collection<C>> collectionFn, Consumer<LambdaSubCollection<D, E>> nestedQuery){
        return selectCollection(null, collectionClass, collectionFn, nestedQuery);
    }

    <A, B, C, D extends LambdaSubCollection<D, E>, E> W  selectCollection(String tableAlias, Class<A> collectionClass, SFunction<B, Collection<C>> collectionFn, Consumer<LambdaSubCollection<D, E>> nestedQuery);

    /* ================== 多对一/一对一关联 ================== */

    default <A, B, C> W selectAssociation(Class<A> assocClass, SFunction<B, C> assocFn) {
        return selectAssociation(assocClass, assocFn, null);
    }

    default <A, B, C, D extends LambdaSubCollection<D, E> , E> W selectAssociation(Class<A> assocClass, SFunction<B, C> assocFn, Consumer<LambdaSubCollection<D, E>> nestedQuery){
        return selectAssociation(null, assocClass, assocFn, nestedQuery);
    }

    <A, B, C, D extends LambdaSubCollection<D, E> , E> W selectAssociation(String tableAlias, Class<A> assocClass, SFunction<B, C> assocFn, Consumer<LambdaSubCollection<D, E>> nestedQuery);

    /* ================== 原子方法 – 由 AbstractWrapper 实现 ================== */
    W collection(SqlSegment seg);

}